﻿Imports System
Imports System.IO
Imports System.Net
Imports System.Text
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Imports System.Runtime.InteropServices



Public Class Form1
    Private singleCityID As String
    Private Shared resouceToPurify As Integer
    Private Dict As Dictionary(Of String, String)
    Dim researchList As New Dictionary(Of String, ResearchClass)
    Dim Thread As System.Threading.Thread
    Private Server As String = ""
    Private World As String = ""
    Private pollHTTP As String = "/Presentation/Service.svc/ajaxEndpoint/Poll"
    Private purifyHTTP As String = "/Presentation/Service.svc/ajaxEndpoint/ResourceToVoid"
    Private upgradeHTTP As String = "/Presentation/Service.svc/ajaxEndpoint/UpgradeBuilding"
    Private cancelHTTP As String = "/Presentation/Service.svc/ajaxEndpoint/CancelBuild"
    Private researchHTTP As String = "/Presentation/Service.svc/ajaxEndpoint/PlayerActivateTechTreeStep"
    Private cancelUnitHTTP As String = "/Presentation/Service.svc/ajaxEndpoint/CancelUnitProduction"
    Private unitProductionHTTP As String = "/Presentation/Service.svc/ajaxEndpoint/StartUnitProduction"
    Private unitSwapHTTP As String = "/Presentation/Service.svc/ajaxEndpoint/SwapUnitProduction"

    ''' <summary>
    ''' Upgrade and downgrade building button.
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub ButtonSubmit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSubmit.Click
        Dim buildingType As String
        Dim startTime As Long
        Dim stopTime As Long
        Dim queueID As String
        Dim jsonString As String
        Dim request As RequestSender
        Dim response As QueryParser
        Dim query As String

        LabelErrorMsg.Text = ""

        If CheckBoxBuildingLevel.Checked Then
            buildingType = "15"
        Else
            buildingType = "9"
        End If

        startTime = Util.getTime()

        If Not String.IsNullOrWhiteSpace(TextBoxBuildingID.Text) Then
            query = "{""session"":""" + TextBoxSessionID.Text + """,""cityid"":""" + Dict(ComboBoxCityList.Text) + """,""buildingid"":" + TextBoxBuildingID.Text + ",""buildingType"":" + buildingType + ",""isPaid"":true}"
            request = New RequestSender(upgradeHTTP, Server, World)
            jsonString = request.sendRequest(query)

            'TODO: Add check if building was built.

            If CheckBoxDowngrade.Checked And Not String.IsNullOrEmpty(jsonString) Then
                response = New QueryParser(jsonString)

                queueID = response.GetQueueID(TextBoxBuildingID.Text)


                If Not String.IsNullOrWhiteSpace(queueID) Then
                    query = "{""session"":""" + TextBoxSessionID.Text + """,""cityid"":""" + Dict(ComboBoxCityList.Text) + """,""queueid"":" + queueID + "}"
                    request = New RequestSender(cancelHTTP, Server, World)
                    request.sendRequest(query)
                Else
                    LabelErrorMsg.Text = "Failed to Delete Building"
                End If
            End If
        Else
            LabelErrorMsg.Text = "Please enter a Building ID"
        End If

        stopTime = Util.getTime() - startTime

    End Sub


    ''' <summary>
    ''' Calls method to start the thread to purfiy negative resources.
    ''' Passes the Text in the Resources text box
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub ButtonSubmitRes_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSubmitRes.Click
        LabelErrorMsg.Text = ""
        startResourceQuery(TextBoxResources.Text)
    End Sub

    ''' <summary>
    ''' This Function starts a thread to purify resources in the negetive direction. It will not fill up resources
    ''' </summary>
    ''' <param name="numOfResources">The number of resources you want to purify</param>
    ''' <remarks></remarks>
    Private Sub startResourceQuery(ByVal numOfResources As String)
        Dim i As Integer = 0
        Dim validRequest As Boolean = True

        Thread = New System.Threading.Thread(AddressOf Me.loopSendResourceQuery)
        LabelErrorMsg.Text = ""

        singleCityID = Dict(ComboBoxCityList.Text)

        resouceToPurify = CInt(numOfResources)
        If Not String.IsNullOrWhiteSpace(TextBoxSessionID.Text) Or Not String.IsNullOrWhiteSpace(ComboBoxCityList.Text) Then
            Thread.Start()
        Else
            LabelErrorMsg.Text = "Please Enter SessionID and Select A City"
        End If
    End Sub

    ''' <summary>
    ''' The Function that will be threaded. It loops through and purifies till the number of purified resources is met.
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub loopSendResourceQuery()
        Dim i As Integer = 0
        Dim validRequest As Boolean = True
        Dim query As String
        Dim request As RequestSender

        While i < CDec(resouceToPurify) And validRequest
            query = RequestBuilder.createContent(singleCityID, TextBoxSessionID.Text, CheckBoxWood.Checked, CheckBoxStone.Checked, CheckBoxIron.Checked, CheckBoxWheat.Checked)
            request = New RequestSender(purifyHTTP, Server, World)
            validRequest = Convert.ToBoolean(request.sendReserachRequest(query))
            i = i + 1
        End While
    End Sub

    ''' <summary>
    ''' Overloaded function. If you call this one pass a city object so it can fill up the city with resources.
    ''' </summary>
    ''' <param name="city"></param>
    ''' <remarks></remarks>
    Private Sub loopSendResourceQuery(ByVal city As CityClass, ByVal loopNumber As Integer)
        Dim i As Integer = 0
        Dim validRequest As Boolean = True
        Dim query As String
        Dim request As RequestSender

        resouceToPurify = city.getMaxResourcesNeeded()

        While i < CDec(resouceToPurify)
            If validRequest Then
                query = RequestBuilder.createContent(TextBoxSessionID.Text, city)
                request = New RequestSender(purifyHTTP, Server, World)
                validRequest = Convert.ToBoolean(request.sendReserachRequest(query))
                i = i + 1
            ElseIf Not validRequest And loopNumber < 3 Then
                loopSendResourceQuery(city, loopNumber + 1)
            End If

        End While
    End Sub

    ''' <summary>
    ''' Updates the cities in the city dropdown list.
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub ButtonUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonUpdate.Click
        Dim jsonstring As String
        Dim query As String = "{""session"":""" + TextBoxSessionID.Text + """,""requestid"":""1"",""requests"":""\fPLAYER""}"
        Dim request As RequestSender
        Dim response As QueryParser
        World = ConfigurationManager.AppSettings(ComboBoxServerList.Text & "World")
        Server = ConfigurationManager.AppSettings(ComboBoxServerList.Text & "Server")
        LabelErrorMsg.Text = ""
        Dict = New Dictionary(Of String, String)
        ComboBoxCityList.Items.Clear()
        If Not String.IsNullOrWhiteSpace(TextBoxSessionID.Text) Then

            request = New RequestSender(pollHTTP, Server, World)
            jsonstring = request.sendRequest(query)
            If Not String.IsNullOrEmpty(jsonstring) Then
                response = New QueryParser(jsonstring)

                If Not response.setCityDropDownList(Dict) Then
                    LabelErrorMsg.Text = "Please enter a Session ID"
                    disableForm()
                    Exit Sub
                End If

                For Each buildingName In Dict.Keys
                    ComboBoxCityList.Items.Add(buildingName)
                Next

                If Not ComboBoxResearchName.Items.Count > 0 Then

                    jsonstring = My.Computer.FileSystem.ReadAllText("ResearchObject.txt")
                    response = New QueryParser(jsonstring)
                    response.getResearchTitles(researchList)

                    For Each researchTitle In researchList.Keys
                        ComboBoxResearchName.Items.Add(researchTitle)
                    Next
                End If
                LabelErrorMsg.Text = "Success SessionID Updated"
                ComboBoxCityList.SelectedIndex = 0
                enableForm()
            Else
                LabelErrorMsg.Text = "Please enter a Session ID"
                disableForm()
            End If
        Else
            LabelErrorMsg.Text = "Please enter a Session ID"
            disableForm()
        End If

    End Sub

    ''' <summary>
    ''' Disables Editable fields in the form
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub disableForm()
        ButtonSubmit.Enabled = False
        ButtonSubmitRes.Enabled = False
        ButtonFillCities.Enabled = False
        ButtonStopLoop.Enabled = False
        ButtonFillCity.Enabled = False
    End Sub

    ''' <summary>
    ''' Enables editable fields in the form
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub enableForm()
        ButtonSubmit.Enabled = True
        ButtonSubmitRes.Enabled = True
        ButtonFillCities.Enabled = True
        ButtonStopLoop.Enabled = True
        ButtonFillCity.Enabled = True
    End Sub

    ''' <summary>
    ''' Stops
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub ButtonStopLoop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonStopLoop.Click
        Thread.Abort()
    End Sub

    ''' <summary>
    ''' To be done.  Run thread that will get
    ''' Run the query through sendBuildRequest() using the poll HTTP address that will return City ID json object.
    ''' Then with that object run it through a query parser and get a city class object.
    ''' From that city class object fill up the city by running the sendResourceQuery(city as CityClass)
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub ButtonFillCities_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonFillCities.Click
        LabelErrorMsg.Text = ""
        Thread = New System.Threading.Thread(AddressOf Me.fillCities)
        Thread.Start()
    End Sub


    Private Sub fillCities()
        For Each cityID In Dict.Values
            fillcity(cityID)
        Next
    End Sub

    Private Sub ButtonFillCity_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonFillCity.Click
        LabelErrorMsg.Text = ""
        Thread = New System.Threading.Thread(AddressOf Me.fillcity)
        singleCityID = Dict(ComboBoxCityList.Text)
        Thread.Start()
    End Sub


    Private Sub fillcity()
        fillcity(singleCityID)
    End Sub



    Private Sub fillCity(ByVal cityID As String)
        Dim purifyOne As RequestSender

        purifyOne = New RequestSender(purifyHTTP, Server, World)
        purifyOne.sendReserachRequest(RequestBuilder.PurifyResources(TextBoxSessionID.Text, CheckBoxWood.Checked, CheckBoxStone.Checked, CheckBoxIron.Checked, CheckBoxWheat.Checked, getCityClass(cityID), 2000))

        loopSendResourceQuery(getCityClass(cityID), 0)


    End Sub

    Private Sub ComboBoxResearchName_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBoxResearchName.SelectedIndexChanged
        Dim i As Integer = 0

        ComboBoxResearchRank.Items.Clear()

        If researchList.ContainsKey(ComboBoxResearchName.Text) Then
            While i < researchList(ComboBoxResearchName.Text).label.Count
                ComboBoxResearchRank.Items.Add(i + 1)
                i = i + 1
            End While
        End If
        ComboBoxResearchRank.SelectedIndex = 0
    End Sub

    Private Sub btnResearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnResearch.Click
        Dim stepID As String
        Dim validRequest As String
        Dim query As String
        Dim request As RequestSender

        stepID = researchList(ComboBoxResearchName.Text).label(CInt(ComboBoxResearchRank.Text) - 1)

        query = "{""session"":""" + TextBoxSessionID.Text + """,""step"":" + stepID + "}"

        request = New RequestSender(researchHTTP, Server, World)
        validRequest = request.sendReserachRequest(query)

        If (ComboBoxResearchRank.SelectedIndex + 1 < ComboBoxResearchRank.Items.Count) Then
            ComboBoxResearchRank.SelectedIndex = ComboBoxResearchRank.SelectedIndex + 1
        End If
    End Sub

    Private Function getCityClass(ByVal cityId As String) As CityClass
        Dim jsonstring As String
        Dim request As RequestSender
        Dim query As String
        Dim response As QueryParser

        If Not String.IsNullOrWhiteSpace(TextBoxSessionID.Text) Then
            query = "{""session"":""" + TextBoxSessionID.Text + """,""requestid"":""1"",""requests"":""\fCITY:" + cityId + """}"
            request = New RequestSender(pollHTTP, Server, World)
            jsonstring = request.sendRequest(query)

            If Not String.IsNullOrEmpty(jsonstring) Then
                response = New QueryParser(jsonstring)
                Return response.GetCityObject(cityId)
            End If

        Else
            LabelErrorMsg.Text = "Please enter a Session ID"
        End If

        Return Nothing

    End Function

    ''' <summary>
    ''' A test button so when you click it you can debug and see what happens with what ever object you are working with.
    ''' It is used now to look at json STrings.
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub ButtonTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonTest.Click


    End Sub

    Public Const MOD_CONTROL As Integer = 2
    Public Const MOD_ALT As Integer = 1 'Alt key
    Public Const MOD_SHIFT As Integer = 4
    Public Const WM_HOTKEY As Integer = &H312

    <DllImport("User32.dll")> _
    Public Shared Function RegisterHotKey(ByVal hwnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As Integer, ByVal vk As Integer) As Integer
    End Function

    <DllImport("User32.dll")> _
    Public Shared Function UnregisterHotKey(ByVal hwnd As IntPtr, ByVal id As Integer) As Integer
    End Function

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim serverList() As String = ConfigurationManager.AppSettings("ServerList").Split(" ")
        For Each ServerName In serverList
            ComboBoxServerList.Items.Add(ServerName)
        Next
        ComboBoxServerList.SelectedIndex = 0
        RegisterHotKey(Me.Handle, 1, MOD_ALT, Keys.Down)
        RegisterHotKey(Me.Handle, 2, MOD_ALT, Keys.Up)
        RegisterHotKey(Me.Handle, 3, MOD_ALT, Keys.Left)
    End Sub

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)

        If m.Msg = WM_HOTKEY Then
            Dim id As IntPtr = m.WParam
            Select Case (id.ToString)
                Case "1"
                    If ComboBoxCityList.SelectedIndex + 1 < ComboBoxCityList.Items.Count Then
                        ComboBoxCityList.SelectedIndex += 1
                    End If
                Case "2"
                    If ComboBoxCityList.SelectedIndex - 1 >= 0 Then
                        ComboBoxCityList.SelectedIndex -= 1
                    End If
                Case "3"
                    ButtonSubmit_Click(DBNull.Value, EventArgs.Empty)
            End Select
        End If
        MyBase.WndProc(m)
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        UnregisterHotKey(Me.Handle, 1)
        UnregisterHotKey(Me.Handle, 2)
        UnregisterHotKey(Me.Handle, 3)
    End Sub
End Class